package com.wutong.engine.entity;

import com.wutong.engine.anything.GameLogger;
import com.wutong.engine.exception.NotInitialException;
import org.slf4j.Logger;

import java.util.HashMap;
import java.util.Map;

/**
 * 生物类，实现基底可互动实体
 *
 * @author 王益凡
 */
public class Biology extends GameEntity {
    private static final Logger log = GameLogger.getLogger(Boolean.class);

    private static int biologyId = 1000000;
    private final int id;

    // 定义实体数值

    // 当前生命值
    protected double hp;
    // 生命值上限
    protected double maxHp;
    // 基础防御力
    protected double baseDefense;
    // 当前法力值
    protected double mana;
    // 法力值上限
    protected double maxMana;
    // 攻击力
    protected double damage;
    // 暴击率 默认为50%
    protected double criticalStrikeChance = 0.5;
    // 暴击伤害 默认为30%
    protected double criticalHitDamage = 0.3;

    // 实体移动速度: 默认为1
    protected double moveSpeed = 1;

    // 生物状态
    protected final Map<String, BiologicalState> biologicalStates = new HashMap<>();

    // 是否初始化
    protected boolean isInitial = false;


    public Biology(String biologyName) {
        super(biologyName);
        this.id = biologyId++;
        log.info("初始化生物实体 {}: {}", id, biologyName);
    }

    /**
     * 对生物实体数据进行初始化，若未初始化，则报错
     * @param maxHp 生命值上限
     * @param maxMana 法力上限
     * @param baseDefense 基础防御力
     * @param damage 攻击力
     * @param criticalStrikeChance 暴击率
     * @param criticalHitDamage 暴击伤害
     * @param moveSpeed 移动速度
     */
    public void init(double maxHp, double maxMana, double baseDefense, double damage, double criticalStrikeChance, double criticalHitDamage, double moveSpeed) {
        this.hp = this.maxHp = maxHp;
        this.mana = this.maxMana = maxMana;
        this.baseDefense = baseDefense;
        this.criticalHitDamage = criticalHitDamage;
        this.criticalStrikeChance = criticalStrikeChance;
        this.moveSpeed = moveSpeed;

        this.isInitial = true;
        log.info("生物实体初始化完毕");
    }

    public void init(double maxHp, double maxMana, double baseDefense, double damage, double criticalStrikeChance, double criticalHitDamage) {
        this.init(maxHp, maxMana, baseDefense, damage, criticalStrikeChance, criticalHitDamage, 1);
    }

    /**
     * 判断是否进行了初始化
     */
    public void isInitial() {
        if (!isInitial) {
            log.error("生物实体未初始化，请初始化后再进行内容调用");
            throw new NotInitialException();
        }
    }

    /**
     * 添加生物效果，即当前生物身上存在的效果
     * @param biologicalState 生物效果
     */
    public void loadEffect(BiologicalState biologicalState) {
        isInitial();
        this.biologicalStates.put(biologicalState.getStateName(), biologicalState);
    }

    public int getBiologyId() {
        isInitial();
        return this.id;
    }

    public double getHp() {
        isInitial();
        return hp;
    }

    public void setHp(double hp) {
        isInitial();
        this.hp = hp;
    }

    public double getMaxHp() {
        isInitial();
        return maxHp;
    }

    public void setMaxHp(double maxHp) {
        isInitial();
        this.maxHp = maxHp;
    }

    public double getBaseDefense() {
        isInitial();
        return baseDefense;
    }

    public void setBaseDefense(double baseDefense) {
        isInitial();
        this.baseDefense = baseDefense;
    }

    public double getMana() {
        isInitial();
        return mana;
    }

    public void setMana(double mana) {
        isInitial();
        this.mana = mana;
    }

    public double getMaxMana() {
        isInitial();
        return maxMana;
    }

    public void setMaxMana(double maxMana) {
        isInitial();
        this.maxMana = maxMana;
    }

    public double getDamage() {
        isInitial();
        return damage;
    }

    public void setDamage(double damage) {
        isInitial();
        this.damage = damage;
    }

    public double getCriticalStrikeChance() {
        isInitial();
        return criticalStrikeChance;
    }

    public void setCriticalStrikeChance(double criticalStrikeChance) {
        isInitial();
        this.criticalStrikeChance = criticalStrikeChance;
    }

    public double getCriticalHitDamage() {
        isInitial();
        return criticalHitDamage;
    }

    public void setCriticalHitDamage(double criticalHitDamage) {
        isInitial();
        this.criticalHitDamage = criticalHitDamage;
    }

    public double getMoveSpeed() {
        isInitial();
        return moveSpeed;
    }

    public void setMoveSpeed(double moveSpeed) {
        isInitial();
        this.moveSpeed = moveSpeed;
    }

    public BiologicalState getBiologicalState(String biologicalName) {
        isInitial();
        return this.biologicalStates.get(biologicalName);
    }
}
